package com.maezia.tdr.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maezia.tdr.common.CommonConstant;
import com.maezia.tdr.common.DataEntityProvider;
import com.maezia.tdr.common.LockProvider;
import com.maezia.tdr.common.Result;
import com.maezia.tdr.common.enums.FieldSourceEnum;
import com.maezia.tdr.common.enums.StatusCodeEnum;
import com.maezia.tdr.domain.dto.ReportInfoDto;
import com.maezia.tdr.domain.po.TestDriveReport;
import com.maezia.tdr.service.RedisMessageService;
import com.maezia.tdr.service.ReportService;
import com.maezia.tdr.utils.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ReportPocessingServiceImpl implements RedisMessageService {

    @Autowired
    private ReportService reportService;

    @Autowired
    private LockProvider lockProvider;

    @Autowired
    private DataEntityProvider dataEntityProvider;

    @Value("${com.maezia.tdr.gdc-info-url}")
    private String gdcInfoUrl;

    @Override
    public void pocessing(String message) throws Exception {
        log.info("message json:{}", message);
        if(!StringUtils.isEmpty(message)){
            ReportInfoDto infoDto = JSONObject.parseObject(message, ReportInfoDto.class);
            Date startTime = DateUtil.parse(infoDto.getStartTime(), CommonConstant.UTC_DATE_TIME_FORMAT);
            String startTimeStr = DateUtil.format(startTime, CommonConstant.DATE_TIME_FORMAT);

            Date endTime = DateUtil.parse(infoDto.getEndTime(), CommonConstant.UTC_DATE_TIME_FORMAT);
            String endTimeStr = DateUtil.format(endTime, CommonConstant.DATE_TIME_FORMAT);
            String md5 = MD5Utils.getMD5(infoDto.getVehicleId() + "_" + startTimeStr + "_" + endTimeStr);

            //TODO：测试代码，需删除
            infoDto.setStartTime(startTimeStr);
            infoDto.setEndTime(endTimeStr);
            try {
                HttpRequest request = HttpRequest.post(gdcInfoUrl).body(JSONObject.toJSONString(infoDto))
                        .header(Header.CONTENT_TYPE, "application/json");
                String resultJson = request.execute().body();
                if(!StringUtils.isEmpty(resultJson)){
                    Result result = JSONObject.parseObject(resultJson, Result.class);
                    if(result.getCode() == StatusCodeEnum.SUCCESS.getCode() && !ObjectUtils.isEmpty(result.getData())){
                        String jsonStr = JSONObject.toJSONString(result.getData());
                        List<Map> gdcList = JSONArray.parseArray(jsonStr, Map.class);
                        Map<String, Object> gdcData = gdcList.stream().filter(map -> !ObjectUtils.isEmpty(map.get("name")) && !ObjectUtils.isEmpty(map.get("value"))).
                                collect(Collectors.toMap(map -> map.get("name").toString(), map -> map.get("value")));
                        TestDriveReport driveReport = dataEntityProvider.copyProperties(gdcData, TestDriveReport.class, infoDto.getAppKey(), FieldSourceEnum.GDC);
                        driveReport.setCharging(ObjectUtils.isEmpty(gdcData.get("isCharging")) ? null : Integer.valueOf(gdcData.get("isCharging").toString()));
                        if(!ObjectUtils.isEmpty(driveReport)){
                            driveReport.setClientId(infoDto.getAppKey());
                            driveReport.setVinCode(infoDto.getVehicleId());
                            driveReport.setStartTime(startTime);
                            driveReport.setEndTime(endTime);
                            driveReport.setMd5Value(md5);
                            TestDriveReport isExist = reportService.getByMd5(md5);
                            if(ObjectUtils.isEmpty(isExist)){
                                reportService.save(driveReport);
                            }else{
                                driveReport.setUpdateTime(new Date());
                                driveReport.setId(isExist.getId());
                                reportService.updateById(driveReport);
                                reportService.refreshReportCache(reportService.getById(isExist.getId()));
                            }
                        }
                    }
                }
            }catch (Exception e){
                log.error("Exception:", e);
            }finally {
                lockProvider.unLock(CommonConstant.REPORT_TASK_EXE_TIME + CommonConstant.COLON + md5);
            }
        }
    }
}
